#include "ExchangeAdapterConfig.h"
#include "ZZMarketDataProvider.h"
#include "ZZDataConvertHelper.h"
#include "simsingleton.h"
#define TIXML_USE_STL
#include "tinyXML.h"
#include <cctype>
#include "DebugUtils.h"
#include "FixDataConvertHelper.h"
#include "LocalCompile.h"

namespace exchangeadapter_zhengzhou
{
	CZZMarketDataProvider::CZZMarketDataProvider()
	{
		std::memset(&m_stApiAttr,0,sizeof(ApiAttr));
		std::memset(&m_stConnAttr,0,sizeof(ConnAttr));
		std::memset(&m_stLoginAttr,0,sizeof(LoginAttr));
	}

	CZZMarketDataProvider::~CZZMarketDataProvider(void)
	{
	}

	tstring CZZMarketDataProvider::GetName()
	{
		return "ZZMarketDataAdapter";
	}
	
	std::pair<bool,CZZMarketDataProvider::InitParam> 
		CZZMarketDataProvider::InitParam::LoadConfig(
		const tstring& fname)
	{
		InitParam param;
		TiXmlDocument doc(fname.c_str());
		bool loadOkay = doc.LoadFile();
		TiXmlNode* pNode = NULL;
		TiXmlNode* ele = NULL;
		tstring str;

		std::memset(&param,0,sizeof(param));
		if (!loadOkay)
		{
			return std::make_pair(false,param);
		}

		pNode = doc.FirstChild("configure");
		XML_GET_STRING(pNode,"saddressip",param.sAddressIp);
		XML_GET_INT(pNode,"uiport",param.uiPort);
		XML_GET_STRING(pNode,"sparticipantid",param.sParticipantID);
		XML_GET_STRING(pNode,"suserid",param.sUserID);
		XML_GET_STRING(pNode,"spassword",param.sPassword);
		XML_GET_STRING(pNode,"slogpath",param.sLogPath);
		XML_GET_STRING(pNode,"spassword",param.sPassword);
		XML_GET_BOOL(pNode,"bencrypt",param.bEncrypt);
		XML_GET_BOOL(pNode,"bcompress",param.bCompress);
		XML_GET_INT(pNode,"uimonitorport",param.uiMonitorPort);
		XML_GET_STRING(pNode,"slocalip",param.sLocalIP);
		XML_GET_INT(pNode,"uimarketid",param.uiMarketId);
		XML_GET_INT(pNode,"uiheartbeatinterval",param.uiHeartBeatInterval);
		XML_GET_INT(pNode,"uiheartbeattimeout",param.uiHeartBeatTimeout);
		XML_GET_INT(pNode,"uiconnwait",param.uiConnWait);
		XML_GET_STRING(pNode,"sprotocolversion",param.sProVersion);
		XML_GET_STRING(pNode,"sinitpass",param.sInitPasswd);
		XML_GET_STRING(pNode,"sauthserialno",param.sAuthSerNo);
		XML_GET_STRING(pNode,"sauthcode",param.sAuthCode);
		XML_GET_INT(pNode,"uiloginwait",param.uiloginWait);
		XML_GET_INT(pNode,"uisequenceno",param.uiSecquenceNo);

		return std::make_pair(true,param);
	}

	bool CZZMarketDataProvider::Initialize(void* param)
	{
		if(!InitPara(*((InitParam*)param)) || !InitAdapter())
		{
			return false;
		}
		return true;
	}

	bool CZZMarketDataProvider::InitializeByXML( const tchar* configfile )
	{
		std::pair<bool,InitParam> param = 
			InitParam::LoadConfig(configfile);
		if (param.first)
		{
			return Initialize(&param.second);
		}
		else
		{
			return false;
		}
	}

	void CZZMarketDataProvider::UnInitialize()
	{
		CZZCommonAPI *pAdapter = 
			&(simpattern::Singleton_InClass<CZZCommonAPI>::Instance());

		pAdapter->Unregister(BROADCAST,MARKET_DATA,this);
		pAdapter->Uninitialize();
	}

	bool CZZMarketDataProvider::Login(void*)
	{
		CZZCommonAPI *pAdapter = 
			&(simpattern::Singleton_InClass<CZZCommonAPI>::Instance());
		if(!pAdapter->Start(BROADCAST))
			return false;
		return true;
	}

	bool CZZMarketDataProvider::Logout(void*)
	{
		CZZCommonAPI *pAdapter = 
			&(simpattern::Singleton_InClass<CZZCommonAPI>::Instance());
		return pAdapter->Stop(BROADCAST);
	}

	bool CZZMarketDataProvider::InitPara(InitParam &param)
	{
		m_stApiAttr.modeThread = MULTI_THREAD_MODE;
		m_stApiAttr.strLogPath = param.sLogPath;
		m_stApiAttr.dwMonitorPort = param.uiPort;

		m_stConnAttr.bEncrypt = param.bEncrypt;
		m_stConnAttr.bCommpress = param.bCompress;
		m_stConnAttr.idMarket = param.uiMarketId;
		m_stConnAttr.dwHeartBeatInterval = param.uiHeartBeatInterval;
		m_stConnAttr.dwHeartBeatTimeout = param.uiHeartBeatTimeout;
		m_stConnAttr.strIPAddress = param.sAddressIp;
		m_stConnAttr.dwPort = param.uiPort;
		m_stConnAttr.fdWait = param.uiConnWait;

		m_stLoginAttr.strMemberID = param.sParticipantID;
		m_stLoginAttr.strTraderID = param.sUserID;
		m_stLoginAttr.strPasswd = param.sPassword;
		m_stLoginAttr.strLoginIP = param.sLocalIP;
		m_stLoginAttr.strProtocolVersion = param.sProVersion;
		m_stLoginAttr.strInitPassword = param.sInitPasswd;
		m_stLoginAttr.strAuthSerialNo = param.sAuthSerNo;
		m_stLoginAttr.strAuthCode = param.sAuthCode;
		m_stLoginAttr.fdWait = param.uiloginWait;
		m_stLoginAttr.dwSeNo = param.uiSecquenceNo;
		
		return true;
	}

	bool CZZMarketDataProvider::InitAdapter()
	{
		CZZCommonAPI *pAdapter = 
			&(simpattern::Singleton_InClass<CZZCommonAPI>::Instance());
		if(!pAdapter->Initialize(m_stApiAttr))
			return false;
		return pAdapter->Register(BROADCAST,m_stConnAttr,m_stLoginAttr,
			MARKET_DATA,this);
	}

	void CZZMarketDataProvider::OnAdapterQuoteRecieve(CZZPackage &package)
	{
		Quote quote;
		DoM dom;
		FIX::Message msg;
		std::memset(&quote,0,sizeof(quote));
		std::memset(&dom,0,sizeof(dom));
		CDataConvert::TranslateQuoteToPublic(package,&quote);
		Quote2Dom(quote,&dom);
		//OnDoMRecieve(dom);
		FixDataConvertHelper::InternalToFix(RMMS_NS::RMMS_CN_ZZ,dom,&msg);
	}

	void CZZMarketDataProvider::OnAdmRsp(int32 pid,CZZPackage &package,
		FlowType flowtype)
	{
		UNREF_VAR(pid);
		UNREF_VAR(package);
		UNREF_VAR(flowtype);
		PriOnLogin();
	}

	bool CZZMarketDataProvider::SupportDoM()
	{
		return false;
	}

	int32 CZZMarketDataProvider::OnNetErr()
	{
		CZZCommonAPI *pAdapter = 
			&(simpattern::Singleton_InClass<CZZCommonAPI>::Instance());
		PriOnNetDisconnected();
		int32 i = 0;
		while (3 > i){
			if(pAdapter->Register(BROADCAST,m_stConnAttr,m_stLoginAttr,
				MARKET_DATA,this) && pAdapter->Start(BROADCAST)){
				PriOnNetConnected();
				return 0;
			}
			i++;
		}
		
		return -1;
	}
}
